﻿//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//----------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.Xml;
using WsdlNS = System.Web.Services.Description;

namespace Tibco.ServiceModel
{
    /// <summary>
    /// Udp Binding Element.  
    /// Used to configure and construct Udp ChannelFactories and ChannelListeners.
    /// </summary>
    public class TibcoTransportBindingElement : TransportBindingElement
    {
        public TibcoTransportBindingElement()
        {
            this.MaxReceivedMessageSize = TibcoDefaults.MaxReceivedMessageSize;
        }

        protected TibcoTransportBindingElement(TibcoTransportBindingElement other)
            : base(other)
        {
            this.Service = other.Service;
            this.Network = other.Network;
            this.Deamon = other.Deamon;
            this.DQName = other.DQName;
        }

        public string Service { get; set; }
        public string Network { get; set; }
        public string Deamon { get; set; }
        public string DQName { get; set; }

        public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            if (typeof(TChannel) == typeof(IRequestChannel))
                return new TibcoRequestChannelFactory(context) as IChannelFactory<TChannel>;
            else
                return new TibcoChannelFactory(context) as IChannelFactory<TChannel>;
        }

        public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            if (!this.CanBuildChannelListener<TChannel>(context))
            {
                throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "Unsupported channel type: {0}.", typeof(TChannel).Name));
            }

            if (typeof(TChannel) == typeof(IInputChannel))
                return new TibcoChannelListener<TChannel>(this, context) as IChannelListener<TChannel>;
            else
                return new TibcoReplyChannelListener<TChannel>(this, context) as IChannelListener<TChannel>;
        }

        /// <summary>
        /// Used by higher layers to determine what types of channel factories this
        /// binding element supports. Which in this case is just IOutputChannel.
        /// </summary>
        public override bool CanBuildChannelFactory<TChannel>(BindingContext context)
        {
            return (typeof(TChannel) == typeof(IOutputChannel) || typeof(TChannel) == typeof(IRequestChannel));
        }

        /// <summary>
        /// Used by higher layers to determine what types of channel listeners this
        /// binding element supports. Which in this case is just IInputChannel.
        /// </summary>
        public override bool CanBuildChannelListener<TChannel>(BindingContext context)
        {
            return (typeof(TChannel) == typeof(IInputChannel) || typeof(TChannel) == typeof(IReplyChannel));
        }

        public override string Scheme
        {
            get
            {
                return TibcoConstants.Scheme;
            }
        }

        public override BindingElement Clone()
        {
            return new TibcoTransportBindingElement(this);
        }

        public override T GetProperty<T>(BindingContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            return context.GetInnerProperty<T>();
        }
    }
}
